home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 1996 April / Software of the Month Club 1996 April.iso / pc / os2 / psutils / src / psresize.c < prev    next >
C/C++ Source or Header  |  1996-02-21  |  5KB  |  181 lines

  1. /* psresize.c
  2.  * Copyright (C) Angus J. C. Duggan 1991-1995
  3.  * See file LICENSE for details.
  4.  *
  5.  * alter pagesize of document
  6.  *
  7.  * Usage:
  8.  *      psresize [-q] [-w<dim>] [-h<dim>] [-ppaper] [-W<dim>] [-H<dim>]
  9.  *            [-Ppaper] [in [out]]
  10.  *              -w<dim> sets the output paper width
  11.  *              -h<dim> sets the output paper height
  12.  *              -ppaper sets the output paper size (width and height) by name
  13.  *              -W<dim> sets the input paper width
  14.  *              -H<dim> sets the input paper height
  15.  *              -Ppaper sets the input paper size (width and height) by name
  16.  */
  17.  
  18. #include "psutil.h"
  19. #include "psspec.h"
  20. #include "pserror.h"
  21. #include "patchlev.h"
  22.  
  23. char *program ;
  24. int pages ;
  25. int verbose ;
  26. FILE *infile ;
  27. FILE *outfile ;
  28. char pagelabel[BUFSIZ] ;
  29. int pageno ;
  30.  
  31. static void usage(void)
  32. {
  33.    fprintf(stderr, "%s release %d patchlevel %d\n", program, RELEASE, PATCHLEVEL);
  34.    fprintf(stderr, "Copyright (C) Angus J. C. Duggan, 1991-1995. See file LICENSE for details.\n");
  35.    fprintf(stderr, "Usage: %s [-q] [-wwidth] [-hheight] [-ppaper] [-Wwidth] [-Hheight] [-Ppaper] [infile [outfile]]\n",
  36.        program);
  37.    fflush(stderr);
  38.    exit(1);
  39. }
  40.  
  41. static void argerror(void)
  42. {
  43.    message(FATAL, "bad dimension\n");
  44. }
  45.  
  46. #define MIN(x,y) ((x) > (y) ? (y) : (x))
  47. #define MAX(x,y) ((x) > (y) ? (x) : (y))
  48.  
  49. void main(int argc, char *argv[])
  50. {
  51.    double scale, rscale;            /* page scale */
  52.    double waste, rwaste;            /* amount wasted */
  53.    double vshift, hshift;            /* page centring shifts */
  54.    int rotate;
  55.    double inwidth = -1;
  56.    double inheight = -1;
  57.    Paper *paper;
  58.    PageSpec *specs;
  59.  
  60. #ifdef PAPER
  61.    if ( (paper = findpaper(PAPER)) != (Paper *)0 ) {
  62.       inwidth = width = (double)PaperWidth(paper);
  63.       inheight = height = (double)PaperHeight(paper);
  64.    }
  65. #endif
  66.  
  67.    vshift = hshift = 0;
  68.    rotate = 0;
  69.  
  70.    infile = stdin;
  71.    outfile = stdout;
  72.    verbose = 1;
  73.    for (program = *argv++; --argc; argv++) {
  74.       if (argv[0][0] == '-') {
  75.      switch (argv[0][1]) {
  76.      case 'q':    /* quiet */
  77.         verbose = 0;
  78.         break;
  79.      case 'w':    /* page width */
  80.         width = singledimen(*argv+2, argerror, usage);
  81.         break;
  82.      case 'h':    /* page height */
  83.         height = singledimen(*argv+2, argerror, usage);
  84.         break;
  85.      case 'p':    /* paper type */
  86.         if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) {
  87.            width = (double)PaperWidth(paper);
  88.            height = (double)PaperHeight(paper);
  89.         } else
  90.            message(FATAL, "paper size '%s' not recognised\n", *argv+2);
  91.         break;
  92.      case 'W':    /* input page width */
  93.         inwidth = singledimen(*argv+2, argerror, usage);
  94.         break;
  95.      case 'H':    /* input page height */
  96.         inheight = singledimen(*argv+2, argerror, usage);
  97.         break;
  98.      case 'P':    /* input paper type */
  99.         if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) {
  100.            inwidth = (double)PaperWidth(paper);
  101.            inheight = (double)PaperHeight(paper);
  102.         } else
  103.            message(FATAL, "paper size '%s' not recognised\n", *argv+2);
  104.         break;
  105.      case 'v':    /* version */
  106.      default:
  107.         usage();
  108.      }
  109.       } else if (infile == stdin) {
  110.      if ((infile = fopen(*argv, OPEN_READ)) == NULL)
  111.         message(FATAL, "can't open input file %s\n", *argv);
  112.       } else if (outfile == stdout) {
  113.      if ((outfile = fopen(*argv, OPEN_WRITE)) == NULL)
  114.         message(FATAL, "can't open output file %s\n", *argv);
  115.       } else usage();
  116.    }
  117. #if defined(MSDOS) || defined(WINNT)
  118.    if ( infile == stdin ) {
  119.       int fd = fileno(stdin) ;
  120.       if ( setmode(fd, O_BINARY) < 0 )
  121.          message(FATAL, "can't open input file %s\n", argv[4]);
  122.     }
  123.    if ( outfile == stdout ) {
  124.       int fd = fileno(stdout) ;
  125.       if ( setmode(fd, O_BINARY) < 0 )
  126.          message(FATAL, "can't reset stdout to binary mode\n");
  127.     }
  128. #endif
  129.    if ((infile=seekable(infile))==NULL)
  130.       message(FATAL, "can't seek input\n");
  131.  
  132.    if (width <= 0 || height <= 0)
  133.       message(FATAL, "output page width and height must be set\n");
  134.  
  135.    if (inwidth <= 0 || inheight <= 0)
  136.       message(FATAL, "input page width and height must be set\n");
  137.  
  138.    /* try normal orientation first */
  139.    scale = MIN(width/inwidth, height/inheight);
  140.    waste = (width-scale*inwidth)*(width-scale*inwidth) +
  141.       (height-scale*inheight)*(height-scale*inheight);
  142.    hshift = (width - inwidth*scale)/2;
  143.    vshift = (height - inheight*scale)/2;
  144.  
  145.    /* try rotated orientation */
  146.    rscale = MIN(height/inwidth, width/inheight);
  147.    rwaste = (height-scale*inwidth)*(height-scale*inwidth) +
  148.       (width-scale*inheight)*(width-scale*inheight);
  149.    if (rwaste < waste) {
  150.       double tmp = width;
  151.       scale = rscale;
  152.       hshift = (width + inheight*scale)/2;
  153.       vshift = (height - inwidth*scale)/2;
  154.       rotate = 1;
  155.       width = height;
  156.       height = tmp;
  157.    }
  158.  
  159.    width /= scale;
  160.    height /= scale;
  161.  
  162.    /* now construct specification list and run page rearrangement procedure */
  163.    specs = newspec();
  164.  
  165.    if (rotate) {
  166.       specs->rotate = 90;
  167.       specs->flags |= ROTATE;
  168.    }
  169.    specs->pageno = 0;
  170.    specs->scale = scale;
  171.    specs->flags |= SCALE;
  172.    specs->xoff = hshift;
  173.    specs->yoff = vshift;
  174.    specs->flags |= OFFSET;
  175.       
  176.    pstops(1, 1, 0, specs, 0.0);        /* do page rearrangement */
  177.  
  178.    exit(0);
  179. }
  180.  
  181.